//实现语音识别子服务
//实现语音识别子服务
#include <brpc/server.h>
#include <butil/logging.h>
#include "asr.hpp"  //语音识别模块封装
#include "etcd.hpp"  //服务注册模块封装
#include "logger.hpp" //日志模块封装
#include "speech.pb.h"  //protobuf 框架代码


namespace chen_im
{
    class SpeechServiceImpl:public chen_im::SpeechService
    {
    public:
        SpeechServiceImpl(const ASRClient::ptr& asr_client)
            :_asr_client(asr_client)
            {}

        ~SpeechServiceImpl(){}

        void SpeechRecognition(google::protobuf::RpcController* controller,
                       const ::chen_im::SpeechRecognitionReq* request,
                       ::chen_im::SpeechRecognitionRsp* response,
                       ::google::protobuf::Closure* done)
        {
            LOG_DEBUG("收到语音转文字请求！" );
            brpc::ClosureGuard rpc_guard(done);
            //1,取出请求中的数据
            //2,调用语音sdk模块进行语音识别，得到响应
            std::string err;
            std::string res = _asr_client->recognize(request->speech_content(), err);
            if(res.empty())
            {
                LOG_ERROR("{} 语音识别失败", request->request_id());
                response->set_request_id(request->request_id());
                response->set_success(false);
                response->set_errmsg("语音识别失败: " + err);
                return;
            }

            // 3， 组织响应
            response->set_request_id(request->request_id());
            response->set_success(true);
            response->set_recognition_result(res);
        }

    private:
        ASRClient::ptr _asr_client;
    };


    class SpeechServer
    {
    public:
        using ptr = std::shared_ptr<SpeechServer>;
        SpeechServer(const ASRClient::ptr asr_client, const Registry::ptr& reg_client,
                    const std::shared_ptr<brpc::Server>& server)
                    :_asr_client(asr_client)
                    ,_reg_client(reg_client)
                    ,_server(server)
        {}

        void start()
        {
            _server->RunUntilAskedToQuit(); //rpc服务器监听端口
        }

        ~SpeechServer(){}
    private:
        ASRClient::ptr _asr_client; //语音识别客户端
        Registry::ptr _reg_client;  //服务注册客户端 --> 向etcd服务器注册
        std::shared_ptr<brpc::Server> _server; //rpc服务端
    };


    class SpeechServerBuilder
    {
    public:
        //构造语音识别客户端对象
        void make_asr_object(const std::string& app_id, const std::string& api_key, const std::string& secret_key)
        {
            _asr_client = std::make_shared<ASRClient>(app_id, api_key, secret_key);
        }

        //用于构造服务注册客户端对象
        void make_reg_object(const std::string& reg_host, const std::string& service_name,const std::string& access_host)
        {
            _reg_client = std::make_shared<Registry>(reg_host); //reg_host->服务注册中心地址
            //service_name-->服务监控根目录       access_host--> 当前实例的外部访问地址
            _reg_client->registry(service_name, access_host);  //服务注册
        }       

        //构建RPC服务器对象
        void make_rpc_server(uint16_t port, int32_t timeout, uint8_t num_threads)
        {
            if(!_asr_client)
            {
                LOG_ERROR("还未初始化语音识别模块！");
                abort();
            }

            _rpc_server = std::make_shared<brpc::Server>();
            SpeechServiceImpl *speech_service = new SpeechServiceImpl(_asr_client);
            int ret = _rpc_server->AddService(speech_service, brpc::ServiceOwnership::SERVER_OWNS_SERVICE);
            if(ret == -1)
            {
                LOG_ERROR("添加rpc服务区失败");
                abort();
            }
                              
            brpc::ServerOptions options;       
            options.idle_timeout_sec = timeout;
            options.num_threads = num_threads;
            ret = _rpc_server->Start(port, &options);
            if (ret == -1) {
                LOG_ERROR("服务启动失败！");
                abort();
            }
        }

        SpeechServer::ptr build()
        {
             if (!_asr_client) {
                LOG_ERROR("还未初始化语音识别模块！");
                abort();
            }
            if (!_reg_client) {
                LOG_ERROR("还未初始化服务注册模块！");
                abort();
            }
            if (!_rpc_server) {
                LOG_ERROR("还未初始化RPC服务器模块！");
                abort();
            }

            SpeechServer::ptr server = std::make_shared<SpeechServer>(
                _asr_client, _reg_client, _rpc_server);

            return server;
        }

    private:
         ASRClient::ptr _asr_client;
        Registry::ptr _reg_client;
        std::shared_ptr<brpc::Server> _rpc_server;
    };
};
